﻿using Microsoft.SharePoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DR5.SPExtend
{
    public class CamlBuilder
    {
        private string query = string.Empty;
        private string filterQuery = string.Empty;
        private List<string> viewFields = new List<string>();
        //bool isFirst = true;

        public CamlBuilder()
        {

        }

        public string Query()
        {
            if (query.IsNullOrEmpty())
            {
                return string.Empty;
            }
            else
            {
                return "<Where>" + query + "</Where>";
            }
        }

        public string AddFilter(ComparsionOperator cOper, string fieldName, ValueTypes type, string value)
        {
            if (type == ValueTypes.UserMulti)
            {
                filterQuery = ("<" + cOper.ToString() + "><FieldRef Name=\"" + fieldName + "\" LookupId=\"true\" /><Value Type=\"" + type + "\">" + value + "</Value></" + cOper.ToString() + ">");
            }
            else
            {
                filterQuery = ("<" + cOper.ToString() + "><FieldRef Name=\"" + fieldName + "\" /><Value Type=\"" + type + "\">" + value + "</Value></" + cOper.ToString() + ">");
            }
            return filterQuery;
        }

        /// <summary>
        /// Combine two filter, if filterQuery2 is not know pass it as string.empty.
        /// </summary>
        /// <param name="lOper"></param>
        /// <param name="filterQuery1"></param>
        /// <param name="filterQuery2"></param>
        public void Combine(LogicalOperator lOper, string filterQuery1, string filterQuery2)
        {
            string combineQuery = "";
            if (filterQuery2.IsNullOrEmpty())
            {
                combineQuery = filterQuery1;
            }
            else
            {
                switch (lOper)
                {
                    case LogicalOperator.And:
                        combineQuery = "<And>" + filterQuery1 + filterQuery2 + "</And>";
                        break;
                    case LogicalOperator.Or:
                        combineQuery = "<Or>" + filterQuery1 + filterQuery2 + "</Or>";
                        break;
                    default:
                        break;
                }
            }
            query = combineQuery;
            //return combineQuery;
        }

        public void CombineFilterQuery(LogicalOperator lOper)
        {
            string combineQuery = "";
            if (query.IsNullOrEmpty())
            {
                combineQuery = filterQuery;
            }
            else
            {
                switch (lOper)
                {
                    case LogicalOperator.And:
                        combineQuery = "<And>" + filterQuery + query + "</And>";
                        break;
                    case LogicalOperator.Or:
                        combineQuery = "<Or>" + filterQuery + query + "</Or>";
                        break;
                    default:
                        break;
                }
            }
            query = combineQuery;
        }

        public void AddViewFields(SPField fld)
        {
            string s = "<FieldRef Name='" + fld.InternalName + "' />";
            viewFields.Add(s);
        }

        public void AddViewFields(string fieldName)
        {
            string s = "<FieldRef Name='" + fieldName + "' />";
            viewFields.Add(s);
        }

        public string GetViewFields()
        {
            return string.Join("", viewFields.ToArray());
        }

        public void CombineFilterQuery(LogicalOperator lo, ComparsionOperator co, string fieldName, ValueTypes type, string fieldValue)
        {
            AddFilter(co, fieldName, type, fieldValue);
            CombineFilterQuery(lo);
        }
    }

    public enum LogicalOperator
    {
        And,
        Or
    }

    public enum ComparsionOperator
    {
        Eq,
        Neq,
        Gt,
        Geq,
        Lt,
        Leq,
        IsNull,
        IsNotNull,
        BeginsWith,
        Contains,
        DateRangesOverlap
    }

    public enum ValueTypes
    {
        TaxonomyFieldType,
        TaxonomyFieldTypeMulti,
        Text,
        Number,
        Currency,
        User,
        UserMulti,
        Note,
        Counter,
        DateTime
    }

}
